<template>
	<e-popup mode="center" :zoom="props.zoom" :show="show" :customStyle="{
			borderRadius: '6px', 
			overflow: 'hidden',
			marginTop: `-${addUnit(props.negativeTop)}`
		}" :closeOnClickOverlay="props.closeOnClickOverlay" :safeAreaInsetBottom="false" :duration="400" @click="clickHandler">
		<view class="e-modal" :style="{
				width: addUnit(props.width),
			}">
			<text class="e-modal__title" v-if="props.title">{{ props.title }}</text>
			<view class="e-modal__content" :style="{
					paddingTop: `${props.title ? 12 : 25}px`
				}">
				<slot>
					<text class="e-modal__content__text">{{ props.content }}</text>
				</slot>
			</view>
			<e-line></e-line>
			<view class="e-modal__button-group" :style="{
					flexDirection: props.buttonReverse ? 'row-reverse' : 'row'
				}">
				<view class="e-modal__button-group__wrapper e-modal__button-group__wrapper--cancel"
					:hover-stay-time="150" hover-class="e-modal__button-group__wrapper--hover"
					:class="[props.showCancelButton && !props.showConfirmButton && 'e-modal__button-group__wrapper--only-cancel']"
					v-if="props.showCancelButton" @tap="cancelHandler">
					<text class="e-modal__button-group__wrapper__text" :style="{
							color: props.cancelColor
						}">{{ props.cancelText }}</text>
				</view>
				<e-line direction="column" v-if="props.showConfirmButton && props.showCancelButton"></e-line>
				<view class="e-modal__button-group__wrapper e-modal__button-group__wrapper--confirm" hover-stay-time="150" hover-class="e-modal__button-group__wrapper--hover"
					:class="[!props.showCancelButton && props.showConfirmButton && 'e-modal__button-group__wrapper--only-confirm']" v-if="$slots.confirmButton">
					<slot name="confirmButton"></slot>
				</view>
				<view class="e-modal__button-group__wrapper e-modal__button-group__wrapper--confirm"
					:hover-stay-time="150" hover-class="e-modal__button-group__wrapper--hover"
					:class="[!props.showCancelButton && props.showConfirmButton && 'e-modal__button-group__wrapper--only-confirm']"
					v-else-if="props.showConfirmButton" @tap="confirmHandler">
					<e-loading-icon v-if="loading"></e-loading-icon>
					<text v-else class="e-modal__button-group__wrapper__text" :style="{
							color: props.confirmColor
						}">{{ props.confirmText }}</text>
				</view>
			</view>
		</view>
	</e-popup>
</template>

<script lang="ts">
	import {defineComponent} from 'vue'
	import mpMixin from "../../libs/mixin/mpMixin";
	/**
	 * Modal 模态框
	 * @description 弹出模态框，常用于消息提示、消息确认、在当前页面内完成特定的交互操作。
	 * @tutorial https://www.uviewui.com/components/modul.html
	 * @property {Boolean}			show				是否显示模态框，请赋值给show （默认 false ）
	 * @property {String}			title				标题内容
	 * @property {String}			content				模态框内容，如传入slot内容，则此参数无效
	 * @property {String}			confirmText			确认按钮的文字 （默认 '确认' ）
	 * @property {String}			cancelText			取消按钮的文字 （默认 '取消' ）
	 * @property {Boolean}			showConfirmButton	是否显示确认按钮 （默认 true ）
	 * @property {Boolean}			showCancelButton	是否显示取消按钮 （默认 false ）
	 * @property {String}			confirmColor		确认按钮的颜色 （默认 '#2979ff' ）
	 * @property {String}			cancelColor			取消按钮的颜色 （默认 '#606266' ）
	 * @property {Boolean}			buttonReverse		对调确认和取消的位置 （默认 false ）
	 * @property {Boolean}			zoom				是否开启缩放模式 （默认 true ）
	 * @property {Boolean}			asyncClose			是否异步关闭，只对确定按钮有效，见上方说明 （默认 false ）
	 * @property {Boolean}			closeOnClickOverlay	是否允许点击遮罩关闭Modal （默认 false ）
	 * @property {String | Number}	negativeTop			往上偏移的值，给一个负的margin-top，往上偏移，避免和键盘重合的情况，单位任意，数值则默认为px单位 （默认 0 ）
	 * @property {String | Number}	width				modal宽度，不支持百分比，可以数值，px，rpx单位 （默认 '650rpx' ）
	 * @property {String}			confirmButtonShape	确认按钮的样式,如设置，将不会显示取消按钮
	 * @event {Function} confirm	点击确认按钮时触发
	 * @event {Function} cancel		点击取消按钮时触发
	 * @event {Function} close		点击遮罩关闭出发，closeOnClickOverlay为true有效
	 * @example <e-modal :show="true" title="提示" content="提示" />
	 */
	export default defineComponent({
		name: "e-modal",
		mixins: [mpMixin],
	});
</script>

<script lang="ts" setup>
	import {
		ref,
		watch,
		toRefs
	} from 'vue'
	import {
		useDefaultProps
	} from '../../libs/hooks'
	import {
		modalProps,
		modalEmits
	} from './props';
	import {
		addUnit
	} from "../../libs/utils/_utils";
	import componentsProps, {
		type DefaultProps
	} from "../../libs/config/componentsProps";

	const {
		modal: modalDefaultProps
	} = toRefs(componentsProps);

	const _props = defineProps(modalProps)

	const props = useDefaultProps < DefaultProps['modal'] > (_props, modalDefaultProps);
	const emit = defineEmits(modalEmits)

	const loading = ref(false)

	watch(() => _props.show, (n) => {
		// 显示modal时重置loading状态
		if (n && loading.value) loading.value = false
	})

	// 点击确定按钮
	const confirmHandler = () => {
		// 如果配置了异步关闭，将按钮值为loading状态
		if (props.value.asyncClose) {
			loading.value = true;
		}
		emit('confirm')
	}
	// 点击取消按钮
	const cancelHandler = () => {
		emit('cancel')
	}
	// 点击遮罩
	// 从原理上来说，modal的遮罩点击，并不是真的点击到了遮罩
	// 因为modal依赖于popup的中部弹窗类型，中部弹窗比较特殊，虽有然遮罩，但是为了让弹窗内容能flex居中
	// 多了一个透明的遮罩，此透明的遮罩会覆盖在灰色的遮罩上，所以实际上是点击不到灰色遮罩的，popup内部在
	// 透明遮罩的子元素做了.stop处理，所以点击内容区，也不会导致误触发
	const clickHandler = () => {
		if (props.value.closeOnClickOverlay) {
			emit('close')
		}
	}
</script>

<style lang="scss" scoped>
	@import "../../libs/theme/modal.scss";
</style>
